package service;

import com.google.gson.JsonObject;
import common.ThreadLocalManager;
import dao.UserMapper;
import entity.User;
import entity.UserExample;
import enums.LoginEnum;
import enums.RegisterEnum;
import httpcode.HttpStatusCodeEnum;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import utils.CookieUtil;
import utils.DateUtil;
import utils.MD5Util;
import vo.ResultVO;

import java.util.List;

/**
 * 用户操作服务
 * Created by weijianyu on 2017/4/5.
 */
@Service
public class UserService {

    private final Logger logger = LogManager.getLogger(UserService.class);

    private final UserMapper userMapper;

    /**
     * cookie生效时间
     */

    @Value("#{configProperties['cookie.past']}")
    private int past;

    /**
     * 构造函数
     * 初始化
     *
     * @param userMapper userMapper
     */
    @Autowired
    public UserService(UserMapper userMapper) {
        Assert.notNull(userMapper, "userMapper must not null");
        this.userMapper = userMapper;
    }

    /**
     * 注册服务
     *
     * @param register 注册信息
     * @return 注册信息
     */
    @Transactional
    public ResultVO<User> registed(User register) {

        ResultVO<User> result = new ResultVO<User>();

        // 验证参数完整性,如果有不完整,返回错误信息
        ResultVO vail = vaildateRegiste(register);
        if (vail != null) {
            return vail;
        }

        // 验证信息重复性,如果重复,返回错误信息
        ResultVO<User> vailExist = exist(register);
        if (vailExist != null) {
            return vailExist;
        }

        String md5Password = MD5Util.encrypt32(register.getPassword());
        if (md5Password == null) {
            result.setCode(RegisterEnum.ERROR_FORMAT_PASSWORD.getCode());
            result.setErrorMessage(RegisterEnum.ERROR_FORMAT_PASSWORD.getMessage());
            return result;
        }
        register.setPassword(md5Password);
        int col = userMapper.insert(register);

        if (col > 0) {
            result.setCode(RegisterEnum.SUCCESS.getCode());
            register.setPassword(null);
            result.setData(register);
            result.setErrorMessage("");
        } else {
            logger.error("保存user:{}失败", register.toString());
            result.setCode(RegisterEnum.ERROR.getCode());
            result.setErrorMessage(RegisterEnum.ERROR.getMessage());
        }
        return result;
    }

    /**
     * 根据用户名查找用户
     *
     * @param userName 用户名
     * @return 用户名符合的用户 如果不存在返回null.
     */
    public User selectUserByUserName(String userName) {

        UserExample userExample = new UserExample();
        userExample.or().andUserNameEqualTo(userName);

        List<User> users = userMapper.selectByExample(userExample);
        if (users.isEmpty()) {
            return null;
        } else {
            return users.get(0);
        }
    }

    /**
     * 根据email查询用户
     *
     * @param email email邮箱
     * @return 邮箱符合的用户 如果不存在返回null.
     */
    public User selectUserByEmail(String email) {
        UserExample userExample = new UserExample();
        userExample.or().andEmailEqualTo(email);

        List<User> users = userMapper.selectByExample(userExample);
        if (users.isEmpty()) {
            return null;
        } else {
            return users.get(0);
        }
    }

    /**
     * 根据phone号码查询用户
     *
     * @param phone 电话号码
     * @return 查询到的用户 如果不存在返回null
     */
    public User selectUserByPhone(String phone) {
        UserExample userExample = new UserExample();
        userExample.or().andPhoneEqualTo(phone);

        List<User> users = userMapper.selectByExample(userExample);
        if (users.isEmpty()) {
            return null;
        } else {
            return users.get(0);
        }
    }

    /**
     * 注册信息完整校验
     *
     * @param user 校验信息
     * @return 错误信息 null为信息完整
     */
    private ResultVO<User> vaildateRegiste(User user) {

        ResultVO<User> resultVail = new ResultVO<User>();

        if (user.getUserName() == null || StringUtils.isEmpty(user.getUserName())) {
            resultVail.setCode(RegisterEnum.VAIL_USERNAME.getCode());
            resultVail.setErrorMessage(RegisterEnum.VAIL_USERNAME.getMessage());
            return resultVail;
        }

        if (user.getEmail() == null || StringUtils.isEmpty(user.getEmail())) {
            resultVail.setCode(RegisterEnum.VAIL_EMAIL.getCode());
            resultVail.setErrorMessage(RegisterEnum.VAIL_EMAIL.getMessage());
            return resultVail;
        }

        if (user.getPassword() == null || StringUtils.isEmpty(user.getPassword())) {
            resultVail.setCode(RegisterEnum.VAIL_PASSWORD.getCode());
            resultVail.setErrorMessage(RegisterEnum.VAIL_PASSWORD.getMessage());
            return resultVail;
        }

        if (user.getPassword() == null || StringUtils.isEmpty(user.getPhone())) {
            resultVail.setCode(RegisterEnum.VAIL_PHONE.getCode());
            resultVail.setErrorMessage(RegisterEnum.VAIL_PHONE.getMessage());
            return resultVail;
        }

        return null;
    }

    /**
     * 登录校验信息完整
     *
     * @param user 验证信息
     * @return 错误信息 如果验证完整成功 返回null
     */
    private ResultVO<JsonObject> vaildateLogin(User user) {

        ResultVO<JsonObject> resultVail = new ResultVO<JsonObject>();

        if (StringUtils.isEmpty(user.getEmail()) || user.getEmail() == null) {
            resultVail.setCode(LoginEnum.VAIL_EMAIL.getCode());
            resultVail.setErrorMessage(LoginEnum.VAIL_EMAIL.getMessage());
            return resultVail;
        }

        if (StringUtils.isEmpty(user.getPassword()) || user.getPassword() == null) {
            resultVail.setCode(LoginEnum.VAIL_PASSWORD.getCode());
            resultVail.setErrorMessage(LoginEnum.VAIL_PASSWORD.getMessage());
            return resultVail;
        }

        return null;
    }

    private ResultVO<User> exist(User user) {

        ResultVO<User> resultExist = new ResultVO<User>();

        User existed;
        // 查询用户名是否已存在
        existed = selectUserByUserName(user.getUserName());
        if (existed != null) {
            resultExist.setCode(RegisterEnum.ERROR_USERNAME.getCode());
            resultExist.setErrorMessage(RegisterEnum.ERROR_USERNAME.getMessage());
            return resultExist;
        }

        // 查询邮箱是否已存在
        existed = selectUserByEmail(user.getEmail());
        if (existed != null) {
            resultExist.setCode(RegisterEnum.ERROR_EMAIL.getCode());
            resultExist.setErrorMessage(RegisterEnum.ERROR_EMAIL.getMessage());
            return resultExist;
        }

        // 查询电话是否已存在
        existed = selectUserByPhone(user.getPhone());
        if (existed != null) {
            resultExist.setCode(RegisterEnum.ERROR_PHONE.getCode());
            resultExist.setErrorMessage(RegisterEnum.ERROR_PHONE.getMessage());
            return resultExist;
        }

        return null;
    }

    /**
     * 登录操作
     *
     * @param user 登录用户
     * @return 登录信息
     */
    public ResultVO<JsonObject> login(User user) {

        ResultVO<JsonObject> result = new ResultVO<JsonObject>();

        // 验证登录信息
        ResultVO<JsonObject> vailLogin = vaildateLogin(user);
        if (vailLogin != null) {
            return vailLogin;
        }

        String md5Password = MD5Util.encrypt32(user.getPassword());
        if (md5Password == null) {
            result.setCode(LoginEnum.ERROR_FORMAT_PASSWORD.getCode());
            result.setErrorMessage(LoginEnum.ERROR_FORMAT_PASSWORD.getMessage());
            return result;
        }
        UserExample userExample = new UserExample();
        userExample.or().andEmailEqualTo(user.getEmail()).andPasswordEqualTo(md5Password);
        List<User> users = userMapper.selectByExample(userExample);

        if (!users.isEmpty()) {
            if (users.size() == 1) {
                // 登录成功
                User loginer = users.get(0);
                loginer.setPassword("");
                String cookie = CookieUtil.jointCookie(loginer.getId(), DateUtil.getFetureDate(past));
                JsonObject cookies = new JsonObject();
                cookies.addProperty("isid", CookieUtil.desEncryption(cookie));
                result.setCode(LoginEnum.SUCCESS.getCode());
                result.setData(cookies);
                result.setErrorMessage("");
            } else {
                logger.error("登录 查询到多个符合条件 users:{}", users.toString());
                result.setCode(LoginEnum.ERROR_LOGIN.getCode());
                result.setErrorMessage(LoginEnum.ERROR_LOGIN.getMessage());
            }
        } else {
            result.setCode(LoginEnum.ERROR.getCode());
            result.setErrorMessage(LoginEnum.ERROR.getMessage());
        }

        return result;
    }

    public ResultVO<User> getLoginer() {
        ResultVO<User> result = new ResultVO<User>();

        User user = ThreadLocalManager.getUserSession();
        user.setPassword(null);
        result.setCode(HttpStatusCodeEnum.SUCCESS.getCode());
        result.setData(user);
        result.setErrorMessage("");

        return result;
    }

    public void test1() {
       UserExample example = new UserExample();
       example.createCriteria().andIdEqualTo(100020);
        List<User> tests = userMapper.selectByExample(example);
        System.out.println("1");

    }

}
